package pacman;
import java.io.File;
import java.io.IOException;

import maze.Barcode;
import maze.Location;
import maze.Maze;
import sensors.realSensors.RealInfraredSensor;
import sensors.realSensors.RealLightSensor;
import sensors.realSensors.RealUltrasonicSensor;
import sensors.virtualSensors.VirtualLightSensor;
import simulation.ColorMap;
import simulation.GuiTest;
import simulation.Simulator;
import Analyser.BarcodeAnalyser;
import Analyser.SectorAnalyserV1;
import Analyser.SectorAnalyserV2;
import behaviour.Explorer;
import behaviour.MazeCorrector;
import behaviour.PacmanFinder;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.ConsumerCancelledException;
import com.rabbitmq.client.ShutdownSignalException;
import communication.Communicator;

public class Main {
	
	
	public static void main (String [] args) throws IOException, ShutdownSignalException, ConsumerCancelledException, InterruptedException{
//		DemoReal();
		//testMaze();
		//testGui();
		//testCommunicator(); FAILS
		
//		testColorMap();
		//testBarcodeAnalyser();
		//testRidingBarcodeAnalyser();
		
	//testExplorer();
		//testRealRobotMazeExplorer();
//		testCrash();
		
//		testSectorAnalyserV2();
		//testSectorAnalyserV1();

		//testRabbit();
		//realandSimulation(args);
		//testGhost();
//		testRobotMovement();
	testOneOfFour();
//		testAngleCorrection();
//		testMazeCorrector();\
//		testFourSimulators();

	}
	private static void testSectorAnalyserV1() throws IOException {
		char[][] walls =  //index with maze[-y][x]
				{{0,1,0,1,0,1,0,1,0},
					{1,2,2,1,2,1,2,2,1},
					{1,1,1,1,2,1,2,2,1},
					{1,2,2,1,2,1,2,2,1},
					{1,1,2,1,2,1,1,1,1}};
				
		Maze maze = new Maze(walls);
		ColorMap colorMap = new ColorMap();
		colorMap.setupMap(maze, maze.getSize(),maze.getSize());
		Simulator simulator = new Simulator(maze, colorMap);
//		Pacman pacman = new Pacman();
//		pacman.setLocation(new Location(1000,1000));
//		simulator.setPacman(pacman);
//		colorMap.AddBarcode(1, 3, "01000110", 0);
//		colorMap.AddBarcode(5, 2, "01110110", 0);
//		colorMap.AddBarcode(0, 2, "01011100", 1);
//		
//		simulator.getMaze().addBarcode(1, 3, "01000110", 0);
//		simulator.getMaze().addBarcode(5, 2, "01110110", 0);
//		simulator.getMaze().addBarcode(0, 2, "01011100", 1);
		Game game = new Game();
		Channel channel = game.getChannel();
		Ghost ghost = new Ghost(new Location(20,20), 0, "Jos",null);
		Communicator communicator = new Communicator();		
		ghost.setCommunicator(communicator);
		ghost.setUltrasonicSensor(new RealUltrasonicSensor(ghost));
		ghost.setLightSensor(new RealLightSensor(ghost));
		ghost.setInfraredSensor(new RealInfraredSensor(ghost));
		ghost.setStrategy(new Explorer(ghost.getMaze()));
		ghost.xOffsetSensor=-4;
		ghost.yOffsetSensor=3;
		SectorAnalyserV1 sectorAnalyser =  new SectorAnalyserV1();
//		sectorAnalyser.readingsPerQuadrant = 5;
//		sectorAnalyser.angleMargin = 20;
		ghost.sectorAnalyser = sectorAnalyser;
		
		simulator.addGhost(ghost, new Location(20, 20), 0);
		simulator.speed = 800;
		
		GuiTest Gui = new GuiTest(simulator);
		
		Thread t1 = new Thread(new GhostRunner(ghost));
		t1.start();
	}
	private static void testSectorAnalyserV2() throws IOException {
		char[][] walls =  //index with maze[-y][x]
				{{0,1,0,1,0,1,0,1,0},
					{1,2,2,1,2,1,2,2,1},
					{1,1,1,1,2,1,2,2,1},
					{1,2,2,1,2,1,2,2,1},
					{1,1,2,1,2,1,1,1,1}};
				
		Maze maze = new Maze(walls);
		ColorMap colorMap = new ColorMap();
		colorMap.setupMap(maze, maze.getSize(),maze.getSize());
		Simulator simulator = new Simulator(maze, colorMap);
//		Pacman pacman = new Pacman();
//		pacman.setLocation(new Location(1000,1000));
//		simulator.setPacman(pacman);
//		colorMap.AddBarcode(1, 3, "01000110", 0);
//		colorMap.AddBarcode(5, 2, "01110110", 0);
//		colorMap.AddBarcode(0, 2, "01011100", 1);
//		
//		simulator.getMaze().addBarcode(1, 3, "01000110", 0);
//		simulator.getMaze().addBarcode(5, 2, "01110110", 0);
//		simulator.getMaze().addBarcode(0, 2, "01011100", 1);
		
		Ghost ghost = new Ghost(new Location(20,20), 0, "Jos");
		Communicator communicator = new Communicator();		
		ghost.setCommunicator(communicator);
		ghost.setUltrasonicSensor(new RealUltrasonicSensor(ghost));
		ghost.setLightSensor(new RealLightSensor(ghost));
		ghost.setInfraredSensor(new RealInfraredSensor(ghost));
		ghost.setStrategy(new Explorer(ghost.getMaze()));
		ghost.xOffsetSensor=-4;
		ghost.yOffsetSensor=1;
		ghost.frontCompensation=4;
		SectorAnalyserV2 sectorAnalyser =  new SectorAnalyserV2();
		sectorAnalyser.readingsPerQuadrant = 5;
		sectorAnalyser.angleMargin = 20;
		ghost.sectorAnalyser = sectorAnalyser;
		
		simulator.addGhost(ghost, new Location(20, 20), 0);
		simulator.speed = 800;
		
		GuiTest Gui = new GuiTest(simulator, null);
		
		Thread t1 = new Thread(new GhostRunner(ghost));
		t1.start();
	}

	private static void testCrash() throws IOException {
		char[][] walls = { //index with maze[-y][x]
				{2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2}, 
				{1,1,2,1,2,1,2,2,2,2,1,2,1,2,2,1,2,1,2,1,2,1,1},
				{1,2,2,1,2,1,2,1,1,1,2,1,2,2,1,1,2,1,2,1,2,1,1},
				{1,2,1,2,1,1,2,2,2,1,2,1,2,2,2,1,2,2,2,1,2,2,1},
				{1,2,1,1,2,1,2,1,2,1,2,2,1,2,2,1,1,2,1,2,1,1,1},
				{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}};
		

		
		Maze maze = new Maze(walls);
		ColorMap colorMap = new ColorMap();
		colorMap.setupMap(maze, maze.getSize(),maze.getSize());
		Simulator simulator = new Simulator(maze, colorMap);
		Pacman pacman = new Pacman();
		pacman.setLocation(new Location(1000,1000));
		simulator.setPacman(pacman);
		colorMap.AddBarcode(1, 3, "01000110", 0);
		colorMap.AddBarcode(5, 2, "01110110", 0);
		colorMap.AddBarcode(0, 2, "01011100", 1);
		
		simulator.getMaze().addBarcode(1, 3, "01000110", 0);
		simulator.getMaze().addBarcode(5, 2, "01110110", 0);
		simulator.getMaze().addBarcode(0, 2, "01011100", 1);
		
	    Game game = new Game();
		Channel channel = game.getChannel();
		Ghost ghost = new Ghost(new Location(20,20), 0, "Jos");
		ghost.setStrategy(new Explorer(ghost.getMaze()));
		ghost.sectorAnalyser = new SectorAnalyserV2();
		Ghost[] ghosts = {ghost};
		
		game.setGhosts(ghosts);
		
		simulator.addGhost(ghost, new Location(140, 140), 0);
		// speed ook readsize barcode nodig om aan te passen.
		simulator.speed = 800;
		GuiTest Gui = new GuiTest(simulator, game);
		
		Thread t1 = new Thread(new GhostRunner(ghost));
		t1.start();
		
		
	}

	private static void testAngleCorrection() throws IOException {
		Game game = new Game();
		Maze maze = game.getParser().parseMaze(new File("../PenOTiles/wolfraam.txt"));
		ColorMap colorMap = new ColorMap();
		colorMap.setupMap(maze, maze.getSize(),maze.getSize());
		Simulator simulator = new Simulator(maze, colorMap);
		Ghost[] ghosts = game.getGhosts();
		Ghost ghost = ghosts[0];
		ghost.xOffsetSensor=-4;
		ghost.yOffsetSensor=3;
		ghost.setInfraredSensor(new RealInfraredSensor(ghost));
		ghost.setLightSensor(new RealLightSensor(ghost));
		ghost.setUltrasonicSensor(new RealUltrasonicSensor(ghost));
		Communicator communicator = new Communicator();		
		ghost.setCommunicator(communicator);
		//Explorer02 explorer = new Explorer02(ghost.getMaze());
		//explorer.sim = simulator;
		//explorer.g = ghost;
		//ghost.strategy = explorer;
		int[][] positions = game.getPositions();
		simulator.addGhost(ghost, new Location(positions[0][0], positions[0][1]), 0);
		simulator.getMaze().draw(-1, -1);
		GuiTest Gui = new GuiTest(simulator, game);


	}

	private static void Demo() throws IOException, ShutdownSignalException, ConsumerCancelledException, InterruptedException
	{
		Game game = new Game();
		Maze maze = game.getParser().parseMaze(new File("/home/s0219269/workspace/P&O/src/pacman/wolfraam.txt"));
		ColorMap colorMap = new ColorMap();
		colorMap.setupMap(maze, maze.getSize(),maze.getSize());
		Simulator simulator = new Simulator(maze, colorMap);
		Pacman pacman = game.getPacman();
		simulator.setPacman(pacman);
		for(Barcode b : maze.getBarcodes()) colorMap.AddBarcode(b.getX(), b.getY(), b.getCode(), b.getDirection());
		Ghost[] ghosts = game.getGhosts();
		Ghost ghost = ghosts[0];//new Ghost(new Location(20,20), 0, "Jos");
		Ghost ghost1 = ghosts[1];//new Ghost(new Location(20,20), 0, "Jef");
		Ghost ghost2 = ghosts[2];//new Ghost(new Location(20,20), 0, "Jan");
		Ghost ghost3 = ghosts[3];//new Ghost(new Location(20,20), 0, "Jeroen");
		//Ghost[] ghosts = {ghost, ghost1, ghost2, ghost3};
		//game.setGhosts(ghosts);
		/*ConnectionFactory factory = new ConnectionFactory();
        factory.setHost(Config.HOST_NAME);
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();
        channel.exchangeDeclare(Config.EXCHANGE_NAME, "fanout");*/
		ghost.setStrategy(new Explorer(ghost.getMaze()));
		ghost1.setStrategy( new Explorer(ghost1.getMaze()));
		ghost2.setStrategy(new Explorer(ghost2.getMaze()));
		ghost3.setStrategy(new Explorer(ghost3.getMaze()));
		//Explorer02 explorer = new Explorer02(ghost.getMaze());
		//explorer.sim = simulator;
		//explorer.g = ghost;
		//ghost.strategy = explorer;
		int[][] positions = game.getGhostPositions();
		simulator.addGhost(ghost, new Location(positions[0][0], positions[0][1]), 0);
		simulator.addGhost(ghost1, new Location(positions[1][0], positions[1][1]), 0);
		simulator.addGhost(ghost2, new Location(positions[2][0], positions[2][1]), 0);
		simulator.addGhost(ghost3, new Location(positions[3][0], positions[3][1]), 0);
		simulator.speed = 600;
		simulator.getMaze().draw(-1, -1);
		GuiTest Gui = new GuiTest(simulator, game);
		
		Thread t1 = new Thread(new GhostRunner(ghost));
		Thread t2 = new Thread(new GhostRunner(ghost1));
		Thread t3= new Thread(new GhostRunner(ghost2));
		Thread t4 = new Thread(new GhostRunner(ghost3));
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
	private static void testRobotMovement() throws IOException, ShutdownSignalException, ConsumerCancelledException, InterruptedException
	{
		Game game = new Game();
		Maze maze = game.getParser().parseMaze(new File("../PenOTiles/wolfraam.txt"));
		ColorMap colorMap = new ColorMap();
		colorMap.setupMap(maze, maze.getSize(),maze.getSize());
		Simulator simulator = new Simulator(maze, colorMap);
		Ghost[] ghosts = game.getGhosts();
		Ghost ghost = ghosts[0];
		ghost.setStrategy (new Explorer(ghost.getMaze()));
		ghost.xOffsetSensor=-4;
		ghost.yOffsetSensor=3;
		ghost.setInfraredSensor(new RealInfraredSensor(ghost));
		ghost.setLightSensor(new VirtualLightSensor(ghost));
		ghost.setUltrasonicSensor(new RealUltrasonicSensor(ghost));
		Communicator communicator = new Communicator();		
		ghost.setCommunicator(communicator);
		//Explorer02 explorer = new Explorer02(ghost.getMaze());
		//explorer.sim = simulator;
		//explorer.g = ghost;
		//ghost.strategy = explorer;
		int[][] positions = game.getGhostPositions();
		simulator.addGhost(ghost, new Location(positions[0][0], positions[0][1]), 0);
		simulator.getMaze().draw(-1, -1);
		GuiTest Gui = new GuiTest(simulator, game);
		Thread t1 = new Thread(new GhostRunner(ghost));
		t1.start();

	}
	private static void DemoReal() throws IOException, ShutdownSignalException, ConsumerCancelledException, InterruptedException
	{
		Game game = new Game();
		Maze maze = game.getParser().parseMaze(new File("../PenOTiles/wolfraam.txt"));
		ColorMap colorMap = new ColorMap();
		colorMap.setupMap(maze, maze.getSize(),maze.getSize());
		Simulator simulator = new Simulator(maze, colorMap);
		Pacman pacman = game.getPacman();
		simulator.setPacman(pacman);
		for(Barcode b : maze.getBarcodes()) colorMap.AddBarcode(b.getX(), b.getY(), b.getCode(), b.getDirection());
//		Ghost[] ghosts = game.getGhosts();
		Ghost ghost = new Ghost(new Location(20,20), 0, "Jos");
		Ghost ghost1 =new Ghost(new Location(20,20), 0, "Jef");
		Ghost ghost2 = new Ghost(new Location(20,20), 0, "Jan");
		Ghost ghost3 = new Ghost(new Location(20,20), 0, "Jeroen");
		//Ghost[] ghosts = {ghost, ghost1, ghost2, ghost3};
		//game.setGhosts(ghosts);
		/*ConnectionFactory factory = new ConnectionFactory();
        factory.setHost(Config.HOST_NAME);
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();
        channel.exchangeDeclare(Config.EXCHANGE_NAME, "fanout");*/
		ghost.setStrategy(new Explorer(ghost.getMaze()));
		ghost1.setStrategy(new Explorer(ghost1.getMaze()));
		ghost2.setStrategy(new Explorer(ghost2.getMaze()));
		ghost3.setStrategy(new Explorer(ghost3.getMaze()));
//		ghost.setInfraredSensor(new RealInfraredSensor(ghost));
//		ghost.setLightSensor(new RealLightSensor(ghost));
//		ghost.setUltrasonicSensor(new RealUltrasonicSensor(ghost));
//		Communicator communicator = new Communicator();		
//		ghost.setCommunicator(communicator);
		//Explorer02 explorer = new Explorer02(ghost.getMaze());
		//explorer.sim = simulator;
		//explorer.g = ghost;
		//ghost.strategy = explorer;
		Location[] positions = game.robotLocations;
		simulator.addGhost(ghost, positions[0], 0);
		simulator.addGhost(ghost1, positions[1], 0);
		simulator.addGhost(ghost2, positions[2], 0);
		simulator.addGhost(ghost3, positions[3], 0);
		simulator.speed = 600;
		simulator.getMaze().draw(-1, -1);
		GuiTest Gui = new GuiTest(simulator, game);
		
		Thread t1 = new Thread(new GhostRunner(ghost));
		Thread t2 = new Thread(new GhostRunner(ghost1));
		Thread t3= new Thread(new GhostRunner(ghost2));
		Thread t4 = new Thread(new GhostRunner(ghost3));
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
	
	
	private static void testRealRobotMazeExplorer() throws IOException {
		/*
		4x6

		?????_ _
		????| | |
		?_?_|   |
		|  _ _| |
		|    _| |
		| | |????
		|_ _|????
		 */
		
		char[][] walls = {
				{0,0,0,0,0,1,0,1,0},
				{0,0,0,0,1,2,1,2,1},
				{0,1,0,1,1,2,2,2,1},
				{1,2,2,1,2,1,1,2,1},
				{1,2,2,2,2,1,1,1,1},
				{1,2,1,2,1,0,0,0,0},
				{1,1,2,1,1,0,0,0,0}};
		
		Maze maze = new Maze(walls);
		ColorMap colorMap = new ColorMap();
		colorMap.setupMap(maze, maze.getSize(), maze.getSize());
		Simulator simulator = new Simulator(maze, colorMap);
		
		Pacman pacman = new Pacman();
		pacman.setLocation(new Location(60, 60));
		Ghost ghost = new Ghost(new Location(20, 20), 90, "Jos");
		Explorer explorer = new Explorer(ghost.getMaze());
		ghost.setStrategy(explorer);
		
		ghost.setInfraredSensor(new RealInfraredSensor(ghost));
		ghost.setLightSensor(new RealLightSensor(ghost));
		ghost.setUltrasonicSensor(new RealUltrasonicSensor(ghost));
		
		Communicator communicator = new Communicator();		
		ghost.setCommunicator(communicator);
		
		simulator.addGhost(ghost, new Location(20, 20), 90);
		simulator.setPacman(pacman);
		
		GuiTest Gui = new GuiTest(simulator, null);
		
		ghost.run();
	}

	private static void testGui() throws IOException
	{
		char[][] walls = { //index with maze[-y][x]
				{2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2}, 
				{1,1,2,1,2,1,2,2,2,2,1,2,1,2,2,1,2,1,2,1,2,1,2,1,2,2,1,2,2,1,2,1,2,1,2,2,1,2,2,2,1},
				{1,2,2,1,2,1,2,1,1,1,2,1,2,2,1,1,2,1,2,1,2,1,2,2,2,1,1,2,1,1,2,2,1,2,2,2,1,2,1,2,1},
				{1,2,1,2,1,1,2,2,2,1,2,1,2,2,2,1,2,2,2,1,2,2,1,1,2,1,2,1,2,1,2,1,1,2,1,1,1,2,1,2,1},
				{1,2,1,1,2,1,2,1,2,1,2,2,1,2,2,1,1,2,1,2,1,1,2,1,2,1,2,1,2,1,2,2,1,1,2,1,2,1,1,2,1},
				{1,2,1,2,2,1,2,1,2,1,2,1,1,1,2,1,1,2,1,2,2,1,2,1,2,1,2,1,2,1,1,1,2,1,2,1,2,1,2,1,1},
				{1,2,1,2,2,2,1,2,2,1,2,1,2,1,2,1,2,1,2,1,2,2,1,2,2,1,2,1,2,1,2,1,2,2,1,1,2,1,2,2,1},
				{1,2,1,2,1,2,1,2,1,2,2,1,2,1,2,1,2,1,2,2,1,2,1,2,1,2,2,1,2,1,2,2,1,2,2,1,2,1,2,1,1},
				{1,2,1,2,1,1,1,2,1,2,1,1,2,1,2,1,2,2,1,2,1,2,1,2,1,2,1,2,1,2,2,2,1,2,1,2,2,2,2,2,1},
				{1,2,1,2,2,2,1,2,1,1,2,1,2,1,2,1,2,1,1,2,1,2,1,2,1,2,1,2,1,2,1,1,1,2,1,2,1,2,1,2,1},
				{1,2,1,2,1,2,1,2,2,1,2,1,2,1,2,1,2,1,2,1,1,2,1,2,1,2,1,2,1,1,2,1,2,2,1,2,1,2,1,2,1},
				{1,1,2,1,1,1,2,1,1,2,2,1,2,1,2,1,2,1,2,1,2,1,1,2,1,2,2,1,1,1,2,2,1,2,1,2,1,2,1,2,1},
				{1,2,1,2,2,1,2,2,1,2,2,1,2,1,2,1,2,1,2,2,2,1,1,2,1,1,2,1,2,2,2,1,1,2,1,2,1,2,1,2,1},
				{1,1,2,1,1,2,2,1,1,2,2,1,2,1,2,1,2,1,2,1,1,1,2,2,2,1,2,2,1,2,1,2,1,2,1,1,2,1,1,2,1},
				{1,2,2,1,2,2,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,1,2,1,2,1,2,1,1,2,1,2,2,2,1,1},
				{1,2,2,2,1,2,1,1,2,1,2,2,1,2,2,1,2,1,2,2,2,1,2,1,2,1,2,1,1,2,1,2,2,1,2,1,2,1,1,2,1},
				{1,1,1,2,1,1,2,1,2,2,1,2,1,2,1,2,2,1,2,2,1,1,2,1,2,2,2,1,1,2,1,2,1,1,2,1,2,1,2,2,1},
				{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
				{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
				{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
				{1,1,2,1,2,1,2,1,2,1,2,1,2,1,1,1,2,1,2,1,2,1,2,1,2,1,2,1,1,1,2,1,2,1,2,1,1,1,2,1,1}};
		
		Maze maze = new Maze(walls);
		ColorMap colorMap = new ColorMap();
		colorMap.setupMap(maze, 20, 20);
		Simulator simulator = new Simulator(maze, colorMap);
		
		Pacman pacman = new Pacman();
		Ghost ghost1 = new Ghost(new Location(60,20), 0, "Jos");
		Ghost ghost2 = new Ghost(new Location(400,400), 0,"Jef");
		Ghost ghost3 = new Ghost(new Location(400,200), 0,"Jan");
		Ghost ghost4 = new Ghost(new Location(200,400), 0,"Joe");
				
		simulator.setPacman(pacman);
		simulator.addGhost(ghost1, ghost1.getLocation(), ghost1.getRotation());
		simulator.addGhost(ghost2, ghost1.getLocation(), ghost1.getRotation());
		simulator.addGhost(ghost3, ghost1.getLocation(), ghost1.getRotation());
		simulator.addGhost(ghost4, ghost1.getLocation(), ghost1.getRotation());
		
		//GuiTest gui = new GuiTest(simulator, maze, colorMap);
	}

	private static void testCommunicator()
	{
		Communicator comm = new Communicator();
		comm.travel(20);
		System.out.println(comm.getDistance());
	}
	
	private static void testGhost() throws IOException{
		ColorMap colorMap = new ColorMap();
		Maze maze= new Maze(100);
		Simulator simulator = new Simulator(maze, colorMap);
		Ghost ghost = new Ghost(new Location(0,0), 0, "Jan");
		simulator.addGhost(ghost, new Location(0,0), 0);
		ghost.run();
	}
	
	private static void testMaze()
	{
		/**
		 * Test Maze:
		 * 
		 *  _ _ _
		 * |  _  |
		 * | |_| |
		 * |_ _ _|
		 * 
		 * 2121212
		 * 1221221
		 * 1211121
		 * 1121211
		 * 
		 */
		/**char mazedata[4][7] = {
				{2,1,2,1,2,1,2},
				{1,2,2,1,2,2,1},
				{1,2,1,1,1,2,1},
				{1,1,2,1,2,1,1}
		}
		Maze maze = new Maze(mazedata);	
		
		Ghost ghost = new Ghost(new Location(0.0,0.0), maze);
		
		System.out.println("Start locatie");
		System.out.println(ghost.getLocation());
		System.out.println("Start rotatie");
		System.out.println(ghost.getRotation());
		System.out.println("Ultrasonic:");
		System.out.println(ghost.getUltrasonicSensor().getDistance());
		
		
		Simulator simulator = new Simulator();
		Pacman pacman = new Pacman(new Location(40,0), simulator);
		simulator.addGhost(ghost);
		simulator.setPacman(pacman);
		System.out.println("InfraRed:");
		System.out.println(ghost.getInfraredSensor().getDirection());
		
		ghost.rotate(90);
		System.out.println("InfraRed:");
		System.out.println(ghost.getInfraredSensor().getDirection());
		
		ghost.rotate(-45);
		System.out.println("InfraRed:");
		System.out.println(ghost.getInfraredSensor().getDirection());
		
		ghost.rotate(135);
		System.out.println("InfraRed:");
		System.out.println(ghost.getInfraredSensor().getDirection()); **/
	}
	
	private static void testColorMap()
	{
		ColorMap colorMap = new ColorMap();
		
		//colorMap.testReadImage();
		//colorMap.testAddBarcode();		
		colorMap.setupMap();
		colorMap.distortion = 10;
		//colorMap.testGetSensorReading();
		colorMap.TestReadValueOverlap();
		
	}
	
	private static void testBarcodeAnalyser()
	{
		BarcodeAnalyser analyser = new BarcodeAnalyser();
		
		//analyser.TestGetLastPossibleReading();
		//analyser.TestCalculateBarcode();
		analyser.TestUpdate();
	}
	
	private static void testRidingBarcodeAnalyser() throws IOException
	{
		/**
		 * Test Maze:
		 * 
		 *  _ _ _
		 * |  _  |
		 * |b|_| |
		 * |_ _ _|
		 * 
		 * 2121212
		 * 1221221
		 * 1211121
		 * 1121211
		 * (b = barcode 01011010, -y to y)
		 */
		char mazedata[][] = {
				{2,1,2,1,2,1,2},
				{1,2,2,1,2,2,1},
				{1,2,1,1,1,2,1},
				{1,1,2,1,2,1,1}
		};
		
		Maze maze = new Maze(mazedata);
		ColorMap colormap = new ColorMap();
		colormap.setupMap(maze, 3, 3);
		colormap.AddBarcode(0, 1, "01101010", 1);
		colormap.AddBarcode(0, 0, "01101010", 1);
		
		//colormap.showImage(colormap.tileMap[0][0]);
		colormap.showImage(colormap.tileMap[0][1]);
		//colormap.showImage(colormap.tileMap[0][2]);
		
		Ghost ghost = new Ghost(new Location(20,1), 90, "jos");
		ghost.barcodeAnalyser.SetBrownValue(128);
		
		Simulator simulator = new Simulator(maze, colormap);
		simulator.addGhost(ghost, new Location(20,1), 90);
		//simulator.setPacman(new Pacman(simulator));
		
				
		//simulator.getGhostLocations().put(ghost, new Location(20, 14.6));		
		//System.out.println(ghost.getLightSensor().readValue());
		
		System.out.println("Started");
		ghost.run();
		ghost.travel(99, false);
				
		
		
		int prevReading = 0;
		Location ghostLoc = simulator.getGhostLocations().get(ghost);
		
		while(ghostLoc.y<=85)
		{
			ghostLoc = simulator.getGhostLocations().get(ghost);
			System.out.println(ghostLoc.y);
			
			
			int cReading = ghost.getLightSensor().readValue();
			if(prevReading != cReading)
			{
				prevReading = cReading;
				//System.out.println(cReading+ " Pos: "+ghostLoc.x+" "+ghostLoc.y);
			}
			
		}
		System.out.println("Finished Run");
		ghost.terminated = true;
		System.out.println("Expected barcode: 01010110 (2 times)");
		
		/*
		String output = "";
		for(int i=0; i<ghost.barcodeAnalyser.readings.size(); i++)
		{
			output+=ghost.barcodeAnalyser.readings.get(i);
			output+=" ";			
		}
		System.out.println(output);*/
		
		
		
	}
	
	private static void sleep(int milli)
	{
		try {
			Thread.sleep(milli);
		} catch (InterruptedException e) {
		}
	}
	private static void testMazeCorrector() throws IOException, ShutdownSignalException, ConsumerCancelledException, InterruptedException
	{
		char[][] walls = { //index with maze[-y][x]
				{2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2}, 
				{1,1,2,1,2,1,2,2,2,2,1,2,1,2,2,1,2,1,2,1,2,1,1},
				{1,2,2,1,2,1,2,1,1,1,2,1,2,2,1,1,2,1,2,1,2,1,1},
				{1,2,1,2,1,1,2,2,2,1,2,1,2,2,2,1,2,2,2,1,2,2,1},
				{1,2,1,1,2,1,2,1,2,1,2,2,1,2,2,1,1,2,1,2,1,1,1},
				{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}};
		

		
		Maze maze = new Maze(walls);
		ColorMap colorMap = new ColorMap();
		colorMap.setupMap(maze, maze.getSize(),maze.getSize());
		Simulator simulator = new Simulator(maze, colorMap);
		Pacman pacman = new Pacman();
		pacman.setLocation(new Location(140,140));
		simulator.setPacman(pacman);
		colorMap.AddBarcode(1, 3, "01000110", 0);
		colorMap.AddBarcode(5, 2, "01110110", 0);
		colorMap.AddBarcode(0, 2, "01011100", 1);
		
		simulator.getMaze().addBarcode(1, 3, "01000110", 0);
		simulator.getMaze().addBarcode(5, 2, "01110110", 0);
		simulator.getMaze().addBarcode(0, 2, "01011100", 1);
		
	    Game game = new Game();
		Channel channel = game.getChannel();
		Ghost ghost = new Ghost(new Location(20,20), 0, "Jos");
		Ghost ghost1 = new Ghost(new Location(20,20), 0, "Jef");
		Ghost ghost2 = new Ghost(new Location(20,20), 0, "Jan");
		Ghost ghost3 = new Ghost(new Location(20,20), 0, "Jeroen");
//		ghost.getMaze().addBarcode(3, 0, "01010110", 0);
//		ghost3.getMaze().addBarcode(0, 0, "01010110", 0);
		Ghost[] ghosts = {ghost, ghost1, ghost2, ghost3};
		game.setGhosts(ghosts);
		ghost.setStrategy (new MazeCorrector(ghost.getMaze()));
		ghost1.setStrategy (new MazeCorrector(ghost1.getMaze()));
		ghost2.setStrategy(new MazeCorrector(ghost2.getMaze()));
		ghost3.setStrategy(new MazeCorrector(ghost3.getMaze()));
		//Explorer02 explorer = new Explorer02(ghost.getMaze());
		//explorer.sim = simulator;
		//explorer.g = ghost;
		//ghost.strategy = explorer;
		
		simulator.addGhost(ghost, new Location(140, 140), 0);
		simulator.addGhost(ghost1, new Location(60, 60), 0);
		simulator.addGhost(ghost2, new Location(100, 60), 0);
		simulator.addGhost(ghost3, new Location(20, 140), 0);
		// speed ook readsize barcode nodig om aan te passen.
		simulator.speed = 700;
		simulator.getMaze().draw(-1, -1);
		GuiTest Gui = new GuiTest(simulator, game);
		
		Thread t1 = new Thread(new GhostRunner(ghost));
		Thread t2 = new Thread(new GhostRunner(ghost1));
		Thread t3= new Thread(new GhostRunner(ghost2));
		Thread t4 = new Thread(new GhostRunner(ghost3));
		//t1.start();
		//t2.start();
		//t3.start();
		t4.start();
	}

	private static void testBarcodeReal() throws IOException
	{
		Ghost ghost = new Ghost(new Location(0,0), 0, "Jef");
		ghost.setInfraredSensor(new RealInfraredSensor(ghost));
		ghost.setLightSensor(new RealLightSensor(ghost));
		ghost.setUltrasonicSensor(new RealUltrasonicSensor(ghost));
		ghost.setCommunicator(new Communicator());
		
		char mazedata[][] = {
				{2,1,2,1,2,1,2},
				{1,2,2,1,2,2,1},
				{1,2,1,1,1,2,1},
				{1,1,2,1,2,1,1}
		};
		Maze maze = new Maze(mazedata);	
		ColorMap colormap = new ColorMap();
		colormap.setupMap(maze, 3, 3);
		Simulator sim = new Simulator(maze, colormap);
		ghost.setSimulator(sim);
		
		ghost.run();
		
		ghost.travel(40, false);
		//Wanneer de robot over een gekende en herkende barcode rijdt, output hij deze barcode
		//(ge moet de barcode dus wel nog toevoegen in de barcodeanalyser)
		
		while(true)
		{
			System.out.println(ghost.getLightSensor().readValue());
		}
	}

	private static void testExplorer() throws IOException, ShutdownSignalException, ConsumerCancelledException, InterruptedException
	{
		char[][] walls = { //index with maze[-y][x]
				{2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2}, 
				{1,1,2,1,2,1,2,2,2,2,1,2,1,2,2,1,2,1,2,1,2,1,1},
				{1,2,2,1,2,1,2,1,1,1,2,1,2,2,1,1,2,1,2,1,2,1,1},
				{1,2,1,2,1,1,2,2,2,1,2,1,2,2,2,1,2,2,2,1,2,2,1},
				{1,2,1,1,2,1,2,1,2,1,2,2,1,2,2,1,1,2,1,2,1,1,1},
				{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}};
		

		
		Maze maze = new Maze(walls);
		ColorMap colorMap = new ColorMap();
		colorMap.setupMap(maze, maze.getSize(),maze.getSize());
		Simulator simulator = new Simulator(maze, colorMap);
		Pacman pacman = new Pacman();
//		pacman.setLocation(new Location(180,180));
		pacman.setLocation(new Location(60,180));

		simulator.setPacman(pacman);
		colorMap.AddBarcode(1, 3, "01000110", 0);
		colorMap.AddBarcode(5, 2, "01110110", 0);
		colorMap.AddBarcode(0, 2, "01011100", 1);
		
		simulator.getMaze().addBarcode(1, 3, "01000110", 0);
		simulator.getMaze().addBarcode(5, 2, "01110110", 0);
		simulator.getMaze().addBarcode(0, 2, "01011100", 1);
		
	    Game game = new Game();
		Ghost ghost = new Ghost(new Location(20,20), 0, "Jos",game);
		Ghost ghost1 = new Ghost(new Location(20,20), 0, "Jef",game);
		Ghost ghost2 = new Ghost(new Location(20,20), 0, "Jan",game);
		Ghost ghost3 = new Ghost(new Location(20,20), 0, "Jeroen",game);
		Communicator communicator = new Communicator();		
		ghost.setCommunicator(communicator);
		ghost.setUltrasonicSensor(new RealUltrasonicSensor(ghost));
		ghost.setLightSensor(new RealLightSensor(ghost));
		ghost.setInfraredSensor(new RealInfraredSensor(ghost));
		ghost.setStrategy(new Explorer(ghost.getMaze()));
		ghost.xOffsetSensor=-4;
		ghost.yOffsetSensor=2;
		ghost.frontCompensation=4;
		//ghost.getMaze().addBarcode(3, 0, "01010110", 0);
		//ghost3.getMaze().addBarcode(0, 0, "01010110", 0);
		Ghost[] ghosts = {ghost, ghost1, ghost2, ghost3};
		game.setGhosts(ghosts);
		ghost.setStrategy(new Explorer(ghost.getMaze()));
		ghost1.setStrategy(new Explorer(ghost1.getMaze()));
		ghost2.setStrategy(new Explorer(ghost2.getMaze()));
		ghost3.setStrategy(new Explorer(ghost3.getMaze()));
//		ghost.secondaryStrategy = new PacmanFinder(ghost.getMaze());
//		ghost1.secondaryStrategy = new PacmanFinder(ghost1.getMaze());
//		ghost2.secondaryStrategy = new PacmanFinder(ghost2.getMaze());
//		ghost3.secondaryStrategy = new PacmanFinder(ghost3.getMaze());
		//Explorer02 explorer = new Explorer02(ghost.getMaze());
		//explorer.sim = simulator;
		//explorer.g = ghost;
		//ghost.strategy = explorer;
		
		simulator.addGhost(ghost, new Location(20, 20), 0);
		simulator.addGhost(ghost1, new Location(60, 60), 0);
		simulator.addGhost(ghost2, new Location(100, 60), 0);
		simulator.addGhost(ghost3, new Location(20, 140), 0);
		// speed ook readsize barcode nodig om aan te passen.
		simulator.speed = 1000;
		simulator.getMaze().draw(-1, -1);
		GuiTest Gui = new GuiTest(simulator, game);
		
		Thread t1 = new Thread(new GhostRunner(ghost));
		Thread t2 = new Thread(new GhostRunner(ghost1));
		Thread t3= new Thread(new GhostRunner(ghost2));
		Thread t4 = new Thread(new GhostRunner(ghost3));
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
	
	public static void testFourSimulators() throws IOException{
		char[][] walls = { //index with maze[-y][x]
				{2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2}, 
				{1,1,2,1,2,1,2,2,2,2,1,2,1,2,2,1,2,1,2,1,2,1,1},
				{1,2,2,1,2,1,2,1,1,1,2,1,2,2,1,1,2,1,2,1,2,1,1},
				{1,2,1,2,1,1,2,2,2,1,2,1,2,2,2,1,2,2,2,1,2,2,1},
				{1,2,1,1,2,1,2,1,2,1,2,2,1,2,2,1,1,2,1,2,1,1,1},
				{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}};		
		Maze maze = new Maze(walls);
		
		ColorMap colorMap = new ColorMap();
		colorMap.setupMap(maze, maze.getSize(),maze.getSize());
		colorMap.AddBarcode(1, 3, "01010110", 0);
		colorMap.AddBarcode(5, 2, "01110110", 0);
		colorMap.AddBarcode(0, 2, "01011100", 1);
		
		int numberOfPlayers = 4;
		
		
		
		Pacman pacman = new Pacman();
		pacman.setLocation(new Location(140,140));
		
		Game []games = new Game[numberOfPlayers];
		
		Simulator[] simulators = new Simulator[numberOfPlayers];
		
		Location[] robotLocations = {new Location(140,60),
									new Location(60,60),
									new Location(100,60),
									new Location(20, 140)};
		
		Ghost [] ghosts = new Ghost[numberOfPlayers];
		String [] ghostNames = {"Jos", "Jef", "Jan", "Jeroen"};
		
		Thread [] ghostThreads = new Thread[numberOfPlayers];
		for(int i = 0; i < numberOfPlayers; i++){
			simulators[i] = new Simulator(maze, colorMap);
			games[i] = new Game();
			simulators[i].setPacman(pacman);
			simulators[i].getMaze().addBarcode(1, 3, "01010110", 0);
			simulators[i].getMaze().addBarcode(5, 2, "01110110", 0);
			simulators[i].getMaze().addBarcode(0, 2, "01011100", 1);
			ghosts[i] = new Ghost(new Location(20,20), 0, ghostNames[i], games[i]);
			games[i].addGhost(ghosts[i]);
			ghosts[i].setStrategy(new Explorer(ghosts[i].getMaze()));
			ghosts[i].setSimulator(simulators[i]);
			simulators[i].addGhost(ghosts[i], robotLocations[i], 0);
			simulators[i].speed = 800;
			ghosts[i].sendJOIN();
			
			ghostThreads[i] = new Thread(new GhostRunner(ghosts[i]));
			sleep(1000);
		}	
		
		GuiTest Gui = new GuiTest(simulators[0], games[0]);
		
		for(Thread thread: ghostThreads){
			thread.start();
		}
	}
	
	public static void testOneOfFour() throws IOException{
		char[][] walls = { //index with maze[-y][x]
				{2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2}, 
				{1,1,2,1,2,1,2,2,2,2,1,2,1,2,2,1,2,1,2,1,2,1,1},
				{1,2,2,1,2,1,2,1,1,1,2,1,2,2,1,1,2,1,2,1,2,1,1},
				{1,2,1,2,1,1,2,2,2,1,2,1,2,2,2,1,2,2,2,1,2,2,1},
				{1,2,1,1,2,1,2,1,2,1,2,2,1,2,2,1,1,2,1,2,1,1,1},
				{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}};		
		//Maze maze = new Maze(walls);
		Game game = new Game();
		Maze maze = game.getParser().parseMaze(new File("/home/s0212002/workspace2/P&Osem2/PenOTiles/wolfraam.txt"));
		ColorMap colorMap = new ColorMap();
		colorMap.setupMap(maze, maze.getSize(),maze.getSize());
		for(Barcode b : maze.getBarcodes()) colorMap.AddBarcode(b.getX(), b.getY(), b.getCode(), b.getDirection());
		
		
		
		
		Pacman pacman = new Pacman();
		pacman.setLocation(new Location(140,140));
		
		int numberOfPlayers = 4 ;
		//uniek PER PC
		int playerNumber = 0;
		
		Simulator simulator = new Simulator(maze, colorMap);
		
		Location[] robotLocations = game.robotLocations;
		
		String [] ghostNames = {"Jos", "Jef", "Jan", "Jeroen"};
		
		Thread ghostThread;
		
		simulator.setPacman(pacman);
		
		Ghost ghost = new Ghost(new Location(20,20), 0, ghostNames[playerNumber], game);
		game.addGhost(ghost);
		ghost.setStrategy(new Explorer(ghost.getMaze()));
		ghost.setSimulator(simulator);
		
		ghost.sendJOIN();
		simulator.addGhost(ghost, robotLocations[playerNumber], 0);
		simulator.speed = 800;
		ghostThread = new Thread(new GhostRunner(ghost));
		sleep(100);
		
		GuiTest Gui = new GuiTest(simulator, game);

		ghostThread.start();
	}
	
	public static void realandSimulation(String args[]) throws IOException{
		char[][] walls = { //index with maze[-y][x]
				{0,1,0,1,0,1,0,1,0},
					{1,2,2,1,2,1,2,2,1},
					{1,1,1,1,2,1,2,2,1},
					{1,2,2,1,2,1,2,2,1},
					{1,1,2,1,2,1,1,1,1}};
		

		Communicator communicator = new Communicator();		
		Maze maze = new Maze(walls);
		ColorMap colorMap = new ColorMap();
		colorMap.setupMap(maze, maze.getSize(),maze.getSize());
		Simulator simulator = new Simulator(maze, colorMap);
		Pacman pacman = new Pacman();
//		pacman.setLocation(new Location(180,180));
		pacman.setLocation(new Location(100,60));

		simulator.setPacman(pacman);
		colorMap.AddBarcode(1, 3, "01000110", 0);
		colorMap.AddBarcode(2, 2, "01110110", 0);
		colorMap.AddBarcode(0, 2, "01011100", 1);
		
		simulator.getMaze().addBarcode(1, 3, "01000110", 0);
		simulator.getMaze().addBarcode(2, 2, "01110110", 0);
		simulator.getMaze().addBarcode(0, 2, "01011100", 1);
		
	    Game game = new Game();
		Ghost ghost = new Ghost(new Location(20,20), 0, "Jos",game);
		Ghost ghost1 = new Ghost(new Location(20,20), 0, "Jef",game);
		Ghost ghost2 = new Ghost(new Location(20,20), 0, "Jan",game);
		Ghost ghost3 = new Ghost(new Location(20,20), 0, "Jeroen",game);
		
		ghost.setCommunicator(communicator);
		ghost.setUltrasonicSensor(new RealUltrasonicSensor(ghost));
		ghost.setLightSensor(new RealLightSensor(ghost));
		ghost.setInfraredSensor(new RealInfraredSensor(ghost));
		ghost.setStrategy(new Explorer(ghost.getMaze()));
		ghost.xOffsetSensor=-4;
		ghost.yOffsetSensor=2;
		ghost.frontCompensation=4;
		//ghost.getMaze().addBarcode(3, 0, "01010110", 0);
		//ghost3.getMaze().addBarcode(0, 0, "01010110", 0);
		Ghost[] ghosts = {ghost, ghost1, ghost2, ghost3};
		game.setGhosts(ghosts);
		ghost.setStrategy(new Explorer(ghost.getMaze()));
		ghost1.setStrategy(new Explorer(ghost1.getMaze()));
		ghost2.setStrategy(new Explorer(ghost2.getMaze()));
		ghost3.setStrategy(new Explorer(ghost3.getMaze()));
//		ghost.secondaryStrategy = new PacmanFinder(ghost.getMaze());
//		ghost1.secondaryStrategy = new PacmanFinder(ghost1.getMaze());
//		ghost2.secondaryStrategy = new PacmanFinder(ghost2.getMaze());
//		ghost3.secondaryStrategy = new PacmanFinder(ghost3.getMaze());
		//Explorer02 explorer = new Explorer02(ghost.getMaze());
		//explorer.sim = simulator;
		//explorer.g = ghost;
		//ghost.strategy = explorer;
		
		simulator.addGhost(ghost, new Location(20, 20), 0);
		simulator.addGhost(ghost1, new Location(60, 60), 0);
		simulator.addGhost(ghost2, new Location(100, 140), 0);
		simulator.addGhost(ghost3, new Location(20, 140), 0);
		// speed ook readsize barcode nodig om aan te passen.
		simulator.speed = 800;
		simulator.getMaze().draw(-1, -1);
		GuiTest Gui = new GuiTest(simulator, game);
		
		Thread t1 = new Thread(new GhostRunner(ghost));
		Thread t2 = new Thread(new GhostRunner(ghost1));
		Thread t3= new Thread(new GhostRunner(ghost2));
		Thread t4 = new Thread(new GhostRunner(ghost3));
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
	
}
